import { Icon } from '@iconify/vue'
import {
  ElButton,
  ElCard,
  ElCol,
  ElForm,
  ElFormItem,
  ElInput,
  ElRow,
  ElSpace
} from 'element-plus'
import { defineComponent, onMounted, reactive, toRef, toRefs } from 'vue'
import { VxeGrid } from 'vxe-table'

import { cacheApi, type ICacheNamesItem } from '@/apis'
import { type GridExtOptions, useGridExt } from '@/hooks'
import { getElementFnFromInstance } from '@/utils'

import styles from './index.module.css'

export default defineComponent({
  setup() {
    const state = reactive({
      nowCacheName: '',
      namesGridConfig: {
        showOverflow: true,
        highlightCurrentRow: true,
        columns: [
          {
            type: 'seq',
            title: '序号',
            width: 50
          },
          {
            field: 'cacheName',
            title: '缓存名称',
            align: 'center'
          },
          {
            field: 'remark',
            title: '备注',
            align: 'center'
          },
          {
            title: '操作',
            width: 50,
            align: 'center',
            className: 'columns_operation',
            slots: {
              default: 'columns_operation'
            }
          }
        ],
        onCurrentChange() {
          getCacheKeys()
        }
      } as GridExtOptions,
      keysGridConfig: {
        showOverflow: true,
        highlightCurrentRow: true,
        columns: [
          {
            type: 'seq',
            title: '序号',
            width: 50
          },
          {
            field: 'cacheKey',
            title: '缓存键名',
            align: 'center'
          },
          {
            title: '操作',
            width: 50,
            align: 'center',
            className: 'columns_operation',
            slots: {
              default: 'columns_operation'
            }
          }
        ],
        onCurrentChange() {
          getCacheValue()
        }
      } as GridExtOptions,
      cacheValue: {
        cacheName: '',
        cacheKey: '',
        cacheValue: ''
      },
      valueLoading: false
    })

    const { gridRef: namesGridRef, ...namesGridRestHook } = useGridExt(
      toRef(state, 'namesGridConfig')
    )
    const { gridRef: keysGridRef, ...keysGridRestHook } = useGridExt(
      toRef(state, 'keysGridConfig')
    )
    const { $message } = getElementFnFromInstance()

    /**
     * 获取缓存名
     */
    async function getCacheNames() {
      namesGridRestHook.showLoading()

      const data = await cacheApi.getCacheNames()
      state.namesGridConfig.data = data

      namesGridRestHook.hideLoading()
    }

    /**
     * 获取缓存键
     */
    async function getCacheKeys() {
      const current = namesGridRef.value?.getCurrentRecord()

      if (!current) return

      keysGridRestHook.showLoading()

      clearCacheValue()

      const keys = await cacheApi.getCacheKeys(current.cacheName)

      state.keysGridConfig.data = keys.map(v => ({
        cacheKey: v.replace(`${current.cacheName}:`, '')
      }))
      state.nowCacheName = current.cacheName

      keysGridRestHook.hideLoading()
    }

    /**
     * 清除缓存键
     */
    function clearCacheKeys() {
      state.keysGridConfig.data = []
    }

    /**
     * 获取缓存值
     */
    async function getCacheValue() {
      const nameCurrent = namesGridRef.value?.getCurrentRecord()
      const keyCurrent = keysGridRef.value?.getCurrentRecord()

      if (!nameCurrent) return
      if (!keyCurrent) return

      state.valueLoading = true

      const data = await cacheApi.getCacheValue(
        `${nameCurrent.cacheName}:${keyCurrent.cacheKey}`
      )
      state.cacheValue = {
        ...data,
        cacheValue: JSON.stringify(data.cacheValue)
      }

      state.valueLoading = false
    }

    /**
     * 清除缓存值
     */
    function clearCacheValue() {
      state.cacheValue.cacheKey = ''
      state.cacheValue.cacheName = ''
      state.cacheValue.cacheValue = ''
    }

    /**
     * 刷新缓存名
     */
    async function handleRefreshCacheNames() {
      await getCacheNames()
      clearCacheKeys()
      clearCacheValue()
      $message.success({
        message: '刷新缓存列表成功',
        duration: 1000
      })
    }

    /**
     * 刷新缓存键
     */
    async function handleRefreshCacheKeys() {
      // 缓存列表没选中项时，不执行刷新
      if (!namesGridRef.value?.getCurrentRecord()) {
        $message.warning({
          message: '请先选中缓存列表项',
          duration: 1000
        })
        return
      }

      await getCacheKeys()
      clearCacheValue()
      $message.success({
        message: '刷新键名列表成功',
        duration: 1000
      })
    }

    /**
     * 删除缓存名
     */
    async function handleDeleteCacheName(cacheName: string) {
      namesGridRestHook.showLoading()

      await cacheApi.clearCacheName(cacheName)

      namesGridRestHook.hideLoading()
      $message.success({
        message: '清除缓存名称成功',
        duration: 1000
      })

      if (state.nowCacheName && state.nowCacheName === cacheName) {
        state.keysGridConfig.data = []
      }
    }

    /**
     * 删除缓存键
     */
    async function handleDeleteCacheKey(cacheKey: string) {
      const currentName = namesGridRef.value?.getCurrentRecord()

      const key = `${currentName.cacheName}:${cacheKey}`

      keysGridRestHook.showLoading()

      await cacheApi.clearCacheKey(key)

      keysGridRestHook.hideLoading()
      $message.success({
        message: '清除缓存键名成功',
        duration: 1000
      })
      getCacheKeys()
      clearCacheValue()
    }

    onMounted(() => {
      getCacheNames()
    })

    return {
      ...toRefs(state),
      namesGridRef,
      keysGridRef,
      handleRefreshCacheNames,
      handleRefreshCacheKeys,
      handleDeleteCacheName,
      handleDeleteCacheKey
    }
  },
  render() {
    return (
      <div class={styles.view}>
        <ElRow gutter={15}>
          <ElCol span={8}>
            <ElCard
              shadow="never"
              bodyStyle={{
                height: 'calc(100vh - 185px)'
              }}
            >
              {{
                header: () => (
                  <div class={styles.cardHeader}>
                    <span>缓存列表</span>
                    <ElButton
                      type="primary"
                      size="small"
                      circle
                      plain
                      onClick={this.handleRefreshCacheNames}
                    >
                      {{
                        icon: () => (
                          <Icon icon="@local:icon-park-outline:refresh" />
                        )
                      }}
                    </ElButton>
                  </div>
                ),
                default: () => (
                  <VxeGrid
                    ref={(e: any) => (this.namesGridRef = e)}
                    {...this.namesGridConfig}
                  >
                    {{
                      columns_operation: ({
                        row
                      }: {
                        row: ICacheNamesItem
                      }) => (
                        <ElSpace>
                          <ElButton
                            type="primary"
                            size="small"
                            link
                            onClick={(e: MouseEvent) => {
                              e.stopPropagation()
                              this.handleDeleteCacheName(row.cacheName)
                            }}
                          >
                            {{
                              icon: () => (
                                <Icon icon="@local:icon-park-outline:delete" />
                              )
                            }}
                          </ElButton>
                        </ElSpace>
                      )
                    }}
                  </VxeGrid>
                )
              }}
            </ElCard>
          </ElCol>
          <ElCol span={8}>
            <ElCard
              shadow="never"
              bodyStyle={{
                height: 'calc(100vh - 185px)'
              }}
            >
              {{
                header: () => (
                  <div class={styles.cardHeader}>
                    <span>键名列表</span>
                    <ElButton
                      type="primary"
                      size="small"
                      plain
                      circle
                      onClick={this.handleRefreshCacheKeys}
                    >
                      {{
                        icon: () => (
                          <Icon icon="@local:icon-park-outline:refresh" />
                        )
                      }}
                    </ElButton>
                  </div>
                ),
                default: () => (
                  <VxeGrid
                    ref={(e: any) => (this.keysGridRef = e)}
                    {...this.keysGridConfig}
                  >
                    {{
                      columns_operation: ({
                        row
                      }: {
                        row: { cacheKey: string }
                      }) => (
                        <ElSpace>
                          <ElButton
                            type="primary"
                            size="small"
                            link
                            onClick={(e: MouseEvent) => {
                              e.stopPropagation()
                              this.handleDeleteCacheKey(row.cacheKey)
                            }}
                          >
                            {{
                              icon: () => (
                                <Icon icon="@local:icon-park-outline:delete" />
                              )
                            }}
                          </ElButton>
                        </ElSpace>
                      )
                    }}
                  </VxeGrid>
                )
              }}
            </ElCard>
          </ElCol>
          <ElCol span={8}>
            <ElCard
              shadow="never"
              bodyStyle={{
                height: 'calc(100vh - 185px)'
              }}
            >
              {{
                header: () => <span>缓存内容</span>,
                default: () => (
                  <ElForm v-loading={this.valueLoading}>
                    <ElFormItem label="缓存名称">
                      <ElInput v-model={this.cacheValue.cacheName} readonly />
                    </ElFormItem>
                    <ElFormItem label="缓存键名">
                      <ElInput v-model={this.cacheValue.cacheKey} readonly />
                    </ElFormItem>
                    <ElFormItem label="缓存内容">
                      <ElInput
                        v-model={this.cacheValue.cacheValue}
                        type="textarea"
                        rows={8}
                        readonly
                      />
                    </ElFormItem>
                  </ElForm>
                )
              }}
            </ElCard>
          </ElCol>
        </ElRow>
      </div>
    )
  }
})
